package qc.module.ehs.api.controller;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.*;
import qc.common.core.constants.QCAuthConstant;
import qc.common.core.exception.QCPromptException;
import qc.common.core.tree.QCTreeNode;
import qc.module.ehs.dto.org.EhsOrgDto;
import qc.module.ehs.service.EhsOrgService;
import qc.module.platform.dto.dept.DeptSimpleDto;
import qc.module.platform.dto.user.UserSimpleInfoDto;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * EhsOrgController
 * @author QuCheng Tech
 * @create 2024/5/22
 */
@RestController
@RequestMapping("/org")
public class OrgController {

    @Autowired
    private EhsOrgService service;

    @Autowired
    HttpServletRequest request;

    @Autowired
    private RestTemplatePlatform restTemplatePlatform;

    /**
     * 获取所有
     * @return List<EhsOrgDto> 组织信息DTO集合
     * @author QuCheng Tech
     * @since 2024/5/22
     */
    @GetMapping("/all")
    private List<EhsOrgDto> getAll() {
        return service.getAll();
    }

    /**
     * 获取指定 -支持@RequestParam与@PathVariable两种方式
     * @param id 组织代码
     * @return EhsOrgDto 组织信息DTO
     * @author QuCheng Tech
     * @since 2024/5/22
     */
    @GetMapping("/get")
    public EhsOrgDto getByParam(@RequestParam String id) throws QCPromptException {
        return service.get(id);
    }

    /**
     * 获取指定 -支持@RequestParam与@PathVariable两种方式
     * @param id 组织代码
     * @return EhsOrgDto 组织信息DTO
     * @author QuCheng Tech
     * @since 2024/5/22
     */
    @GetMapping("/get/{id}")
    public EhsOrgDto getByPath(@PathVariable String id) throws QCPromptException {
        return service.get(id);
    }

    /**
     * 新增
     * @param dto 组织信息
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/5/22
     */
    @RequestMapping(value = "/add", method = {RequestMethod.GET, RequestMethod.POST})
    public String add(@RequestBody EhsOrgDto dto) {
        return service.add(dto);
    }

    /**
     * 修改
     * @param dto 组织信息
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/5/22
     */
    @RequestMapping(value = "/update", method = {RequestMethod.POST, RequestMethod.PUT})
    public String update(@RequestBody EhsOrgDto dto) {
        return service.update(dto);
    }

    /**
     * 删除 -支持@RequestParam与@PathVariable两种方式
     * @param id 组织代码
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/5/22
     */
    @DeleteMapping("/delete")
    public String deleteByParam(@RequestParam String id) {
        return service.delete(id);
    }

    /**
     * 删除 -支持@RequestParam与@PathVariable两种方式
     * @param id 组织代码
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/5/22
     */
    @DeleteMapping("/delete/{id}")
    public String deleteByPath(@PathVariable String id) {
        return service.delete(id);
    }

    /**
     * 获取当前用户所属组织信息；参数中的项目编码也可以不传，不传入时从header中获取（优先从header中获取项目编码，如没有再根据token获取）；
     * @return EhsOrgDto
     * @throws QCPromptException
     * @author QuCheng Tech
     * @since 2024/6/11
     */
    @GetMapping("/user")
    public EhsOrgDto getUserOrg() throws QCPromptException {
        List<Integer> deptIds = null;
        //根据项目编码查询当前用户所属的根部门
        HttpHeaders headers = new HttpHeaders();
        headers.add(QCAuthConstant.TOKEN_HEADER_KEY, request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY));
        headers.add(QCAuthConstant.PROJECT_CODE_HEADER_KEY, request.getHeader(QCAuthConstant.PROJECT_CODE_HEADER_KEY));
        //获取用户在指定项目中的根部门集合
        List<DeptSimpleDto> rootDepts = restTemplatePlatform.getProjectValidRootDepts(headers);
        if (rootDepts != null && rootDepts.size() > 0x0) {
            deptIds = rootDepts.stream().map(DeptSimpleDto::getId).collect(Collectors.toList());
        }

        return service.getOrgByDeptIds(deptIds);
    }

    /***
     *获取指定组织代码的部门简要信息List；包含组织代码对应的部门ID和所有子级；
     *
     * @param id 组织代码
     * @return java.util.List<qc.module.platform.dto.dept.DeptSimpleDto>
     * @author QuCheng Tech
     * @since 2025/2/28
     */
    @GetMapping("/deptlist")
    public List<DeptSimpleDto> getOrgDeptSimpleDtoListByParam(@RequestParam(name = "id", required = true) String id) throws QCPromptException {
        return getOrgDeptSimpleDtoList(id);
    }

    /***
     *获取指定组织代码的部门简要信息List；包含组织代码对应的部门ID和所有子级；
     *
     * @param id 组织代码
     * @return java.util.List<qc.module.platform.dto.dept.DeptSimpleDto>
     * @author QuCheng Tech
     * @since 2025/2/28
     */
    @GetMapping("/deptlist/{id}")
    public List<DeptSimpleDto> getOrgDeptSimpleDtoListByPath(@PathVariable(name = "id", required = true) String id) throws QCPromptException {
        return getOrgDeptSimpleDtoList(id);
    }

    /***
     * 获取指定组织代码对应的部门和子级部门List
     *
     * @param orgcode 组织代码
     * @return java.util.List<qc.module.platform.dto.dept.DeptSimpleDto>
     * @author QuCheng Tech
     * @since 2025/2/28
     */
    List<DeptSimpleDto> getOrgDeptSimpleDtoList(String orgcode) throws QCPromptException {
        EhsOrgDto org = service.get(orgcode);
        if (org == null)
            throw new QCPromptException("指定的组织信息不存在");
        if (org.getDeptid() < 0x1)
            throw new QCPromptException("获取到的组织信息中部门ID为空或无效");

        return restTemplatePlatform.getDeptChildsList(org.getDeptid());
    }

    /***
     *获取指定组织代码的部门Tree，包含组织代码对应部门和子级部门
     *
     * @param id 组织代码
     * @return java.util.List<qc.module.platform.dto.dept.DeptSimpleDto>
     * @author QuCheng Tech
     * @since 2025/2/28
     */
    @GetMapping("/depttree")
    public List<QCTreeNode> getOrgDeptTreeByParam(@RequestParam(name = "id", required = true) String id) throws QCPromptException {
        return getOrgDeptTree(id);
    }

    /***
     *获取指定组织代码的部门Tree，包含组织代码对应部门和子级部门
     *
     * @param id 组织代码
     * @return java.util.List<qc.module.platform.dto.dept.DeptSimpleDto>
     * @author QuCheng Tech
     * @since 2025/2/28
     */
    @GetMapping("/depttree/{id}")
    public List<QCTreeNode> getOrgDeptTreeByPath(@PathVariable(name = "id", required = true) String id) throws QCPromptException {
        return getOrgDeptTree(id);
    }

    /***
     * 获取指定组织代码的部门Tree
     *
     * @param orgcode 组织代码
     * @return java.util.List<qc.common.core.tree.QCTreeNode>
     * @author QuCheng Tech
     * @since 2025/3/1
     */
    public List<QCTreeNode> getOrgDeptTree(String orgcode) throws QCPromptException {
        EhsOrgDto org = service.get(orgcode);
        if (org == null)
            throw new QCPromptException("指定的组织信息不存在");
        if (org.getDeptid() < 0x1)
            throw new QCPromptException("获取到的组织信息中部门ID为空或无效");

        return restTemplatePlatform.getDeptChildsTree(org.getDeptid());
    }

    /***
     * 获取指定组织代码中用户所在部门ID集合
     *
     * @param orgCode 组织代码
     * @param headers 需要调用Platform接口使用的请求头
     * @return java.util.List<java.lang.Integer>
     * @author QuCheng Tech
     * @since 2025/3/1
     */
    public List<Integer> getUserDeptIds(String orgCode, HttpHeaders headers) throws QCPromptException {
        if (StringUtils.isNotBlank(orgCode)) {
            //获取组织信息中的根部门ID，再获取根部门下的所有部门，获取用户所在的部门ID集合，2个取交集作为用户所在的部门ID集合
            EhsOrgDto org = service.get(orgCode);
            if (org == null)
                throw new QCPromptException("获取到的组织信息为空");
            if (org.getDeptid() < 0x1)
                throw new QCPromptException("获取到的组织信息中的部门ID无效");

            //根据用户获取有效部门，项目编码和用户token均使用headers中的信息
            List<DeptSimpleDto> userDepts = restTemplatePlatform.getUserCanAccessDepts(headers);
            if (userDepts != null && userDepts.size() > 0x0) {
                //如果用户在项目中关联的部门集合不为空时，才需要获取组织信息中的部门ID和子级部门集合
                List<DeptSimpleDto> orgDepts = restTemplatePlatform.getDeptChildsList(org.getDeptid());
                if (orgDepts != null && orgDepts.size() > 0x0) {
                    List<Integer> orgDeptIds = orgDepts.stream().map(p -> p.getId()).collect(Collectors.toList());

                    List<Integer> result = new ArrayList<>();

                    for (DeptSimpleDto userDept : userDepts) {
                        List<Integer> filterByDeptId = orgDeptIds.stream().filter(p -> p.intValue() == userDept.getId()).collect(Collectors.toList());
                        if (filterByDeptId != null && filterByDeptId.size() > 0x0)
                            orgDeptIds.add(userDept.getId());
                    }

                    return result;
                }
            }
        }

        return null;
    }

    /**
     * 获取指定组织代码的用户简要信息list
     * @param id
     * @return List<EhsOrgDto>
     */
    @GetMapping("/users/{id}")
    public List<UserSimpleInfoDto> getOrgUserSimpleListByPath(@PathVariable(name = "id", required = true) String id) throws QCPromptException {
        return getOrgUserList(id);
    }

    /**
     * 获取指定组织代码的用户简要信息list
     * @param id
     * @return List<EhsOrgDto>
     */
    @GetMapping("/users")
    public List<UserSimpleInfoDto> getOrgUserSimpleListByParam(@RequestParam(name = "id", required = true) String id) throws QCPromptException {
        return getOrgUserList(id);
    }

    /**
     * 根据组织代码获取用户列表的具体实现
     * @param orgCode 组织代码
     * @return List<UserSimpleInfoDto>
     * @throws QCPromptException
     */
    private List<UserSimpleInfoDto> getOrgUserList(String orgCode) throws QCPromptException {
        //1.根据组织代码获取组织信息
        EhsOrgDto org = service.get(orgCode);
        if (org == null) {
            throw new QCPromptException("指定的组织信息不存在");
        }
        if (org.getDeptid() < 0x1) {
            throw new QCPromptException("获取到的组织信息中部门ID为空或无效");
        }

        //2.构建调用platform接口需要请求头
        HttpHeaders headers = new HttpHeaders();
        headers.add(QCAuthConstant.TOKEN_HEADER_KEY, request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY));
        headers.add(QCAuthConstant.PROJECT_CODE_HEADER_KEY, request.getHeader(QCAuthConstant.PROJECT_CODE_HEADER_KEY));

        // 3. 调用Platform接口获取指定部门及子级部分的用户信息
        List<UserSimpleInfoDto> users = restTemplatePlatform.getProjectDeptChildUserSimpleInfoList(org.getDeptid(), headers);

        return users;
    }
}
